#pragma once
#include "Function.hpp"

namespace zzz{

//f(x)=1/(sigma*sqrt(2pi))*exp(-(x-mean)^2/(2*sigma^2))
class GaussianFunction : public Function<double,double>
{
public:
  GaussianFunction()
    :Function<double, double>(MAX_DOUBLE, -MAX_DOUBLE),
    mean_(0),sigma_(0){}
  GaussianFunction(double mean, double sigma)
    :Function<double, double>(MAX_DOUBLE, -MAX_DOUBLE)
  {
    SetParameter(mean,sigma);
  }

  double Evaluate(const double& x)
  {
    return A_*exp(-(x-mean_)*(x-mean_)/(2*sigma_));
  }

  void SetParameter(double mean, double sigma)
  {
    mean_=mean;
    sigma_=sigma;
    s2_=sigma_*sigma_;
    A_=1.0/(sigma*sqrt(2*PI));
  }

  bool CheckInput(const double& x)
  {
    return true;
  }

private:
  double mean_;
  double sigma_;

  double s2_;  //sigma^2
  double A_;    //amplifier
};
}
